import os, amara
from wsgiappclient.namespaces import *
from wsgiappclient.controllers.base import BaseController
from wsgiappclient.utils import get_session, save_session
from wsgiappclient.models.user import User
from wsgiappclient.clientatomentry import ClientAtomEntry

from paste.httpexceptions import *
from paste.request import parse_formvars, get_cookies

from pprint import pprint

class CollectionController(BaseController):

    def __init__(self, app, app_conf={}):
        self.app_conf = app_conf
        self.app = app

    def __call__(self, environ, start_response):
        args = environ['wsgiorg.routing_args'][1]
        func = self.dispatch(environ, start_response, 'action')
        if func:
            return func(environ, start_response)
        return self.app(environ, start_response)

    def GET_edit(self, environ, start_response):
        self.setup(environ, start_response)
        entry_position = self.args['id']
        collection = self.user.get_collection_by_id(self.args['collection_id'])
        if not collection:
            self.sess['flash'] = 'Collection "%s" does not exist.' % self.args['collection_id']
            self.sess.save()
            headers = [
                ('location', self.app_conf['base_url'])
            ]
            raise HTTPTemporaryRedirect(headers=headers)
        
        client = self.user.get_client(str(collection.href))
        fdoc = amara.parse(client.get_collection(str(collection.href)),
                           prefixes=COMMON_PREFIXES)
        edoc = fdoc.feed.entry[int(self.args['id']) - 1]
        entry_url = edoc.xml_xpath(u"atom:link[@rel='edit']")
        if not entry_url:
            print 'not entry_url'
            self.sess['flash'] = "The entry doesn't have an edit url."
            self.sess.save()
            headers = [
                ('location', self.app_conf['base_url'])
            ]
            raise HTTPTemporaryRedirect(headers=headers)
        
        entry_url = str(entry_url[0].href)
        print entry_url
        headers, body = client.get_entry(entry_url)
        if headers.get('status') == '200':
            try:
                doc = amara.parse(body, prefixes=COMMON_PREFIXES)
            except Exception, e:
                print 'error loading atom entry'
                self.sess['flash'] = "Error loading the atom entry."
                self.sess.save()
                headers = [('location', '/')]
                raise HTTPTemporaryRedirect(headers=headers)
        else:
            raise get_exception(int(headers['status']))()

        data = {
            'base_url': self.app_conf['base_url'],
            'openid': self.sess['user_id'],
            'entry_uri': entry_url,
            'collection_uri': collection.href,
            'flash': self.sess.get('flash', ''),
        }
        
        self.sess['flash'] = ''
        self.sess.save()
        environ['xsltemplate.template'] = 'collection/edit/forms.xslt'
        # environ['xsltemplate.params'].update(data)
        environ['xsltemplate.params'] = data
        start_response('200 OK', [('content-type', 'text/html')])
        return [doc.xml()]

    def POST_edit(self, environ, start_response):
        self.setup(environ, start_response)
        entry_uri = self.post.get('entry_uri', None)
        collection_uri = self.post.get('collection_uri', None)
        action = self.post.get('action', 'default')

        if not entry_uri or not collection_uri:
            raise HTTPExpectationFailed("Need entry_uri and collection_uri.")
        if action == 'default':
            return self.get_edit(environ, start_response)

        client = self.user.get_client(collection_uri)
        headers, content = client.get_entry(entry_uri)
        if headers.get('status') != '200':
            raise get_exception(int(headers['status']))()
        atom_entry = ClientAtomEntry(post)
        try:
            new_entry = atom_entry.edit(content, post)
        except Exception, e:
            self.sess['flash'] = str(e)
            self.sess.save()
            print "Exception caught!"
            print e
            return self.get_edit(environ, start_response)
        
        headers, body = client.put_entry(new_entry, entry_uri)
        #pprint(headers)

        if headers.get('status').startswith('20'):
            environ['wsgiappclient.post_edit_data'] = {'updated' : True}
            self.sess['flash'] = 'Entry updated'
            self.sess.save()
            return self.get_edit(environ, start_response)
        raise get_exception(int(headers['status']))()

    def GET_create(self, environ, start_response):
        self.setup(environ, start_response)
        #print "in create"
        collection = self.user.get_collection_by_id(
            int(self.args['collection_id'])
        )
        data = {
            'collection_uri': str(collection.href),
        }
        environ['xsltemplate.params'].update(data)
        environ['xsltemplate.template'] = 'collection/create/forms.xslt'
        entry_template = os.path.join(
            self.app_conf['template_directory'],
            'collection/create/source.xml',
        )
        output = file(entry_template, 'rb').read()
        start_response('200 OK', [('content-type', 'text/html')])
        return [output]

    def POST_create(self, environ, start_response):
        self.setup(environ, start_response)
        collection_uri = self.post.get('collection_uri', None)
        client = self.user.get_client(collection_uri)
        
        data = {}
        atom_entry = ClientAtomEntry(self.post, author=self.user.get_author())
        entry_xml = atom_entry.create(self.post)
        errors = atom_entry.validate(entry_xml)
        if errors:
            for k, v in errors.items():
                data['err_%s' % k] = v
            for k, v in self.post.items():
                if 'atom_' in k:
                    data[k] = v
        else:
            headers, body = client.post_entry(collection_uri, entry_xml, self.post)
            if headers.get('status', '') == '201':
                data['location'] = headers['location']
            else:
                data['location'] = '%s - %s' % (headers, body)
                for k, v in self.post.items():
                    data[k] = v
        environ['xsltemplate.params'].update(data)
        return self.GET_create(environ, start_response)

    def GET_collection(self, environ, start_response):
        self.setup(environ, start_response)
        #print "in get_collection"
        #print args
        
        if self.args.get('action'):
            action = self.args['action']
            if action == 'delete' and self.post.get('collection_uri'):
                collection = self.post['collection_uri']
                self.user.delete_collection(collection)
        new_loc = urlparse.urljoin(self.app_conf['base_url'], self.sess['user_id'])
        headers = [('location', new_loc)]
        start_response('303 See Other', headers)
        return ['redirecting...']

